package com.leyou.order.service.impl;

import com.leyou.common.enums.ExceptionEnum;
import com.leyou.common.exception.LyException;
import com.leyou.common.threadlocals.UserHolder;
import com.leyou.common.utils.BeanHelper;
import com.leyou.common.utils.IdWorker;
import com.leyou.item.client.ItemClient;
import com.leyou.item.dto.SkuDTO;
import com.leyou.order.dto.CartDTO;
import com.leyou.order.dto.OrderDTO;
import com.leyou.order.entity.Order;
import com.leyou.order.entity.OrderDetail;
import com.leyou.order.entity.OrderLogistics;
import com.leyou.order.enums.OrderStatusEnum;
import com.leyou.order.mapper.OrderDetailMapper;
import com.leyou.order.mapper.OrderLogisticsMapper;
import com.leyou.order.mapper.OrderMapper;
import com.leyou.order.service.OrderService;
import com.leyou.order.vo.OrderDetailVO;
import com.leyou.order.vo.OrderLogisticsVO;
import com.leyou.order.vo.OrderVO;
import com.leyou.user.client.UserClient;
import com.leyou.user.dto.AddressDTO;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * Created by IntelliJ IDEA.
 *
 * @author: wangzibeng
 * Date: 2019/5/20 0020
 * Time: 10:25
 */
@Service
public class OrderServiceImpl implements OrderService {
    @Autowired
    private OrderLogisticsMapper orderLogisticsMapper;
    @Autowired
    private OrderDetailMapper orderDetailMapper;
    @Autowired
    private OrderMapper orderMapper;
    @Autowired
    private ItemClient itemClient;
    @Autowired
    private UserClient userClient;

    @Override
    public Long createOrder(OrderDTO orderDTO) {
        Long orderId;
        // 1 order
        Order order = new Order();
        // 1.1 订单编号
        IdWorker idWorker = new IdWorker();
        orderId = idWorker.nextId();
        order.setOrderId(orderId);
        // 1.2 登录用户
        Long userId = UserHolder.getUser();
        order.setUserId(userId);
        // 1.3 金额相关信息
        List<CartDTO> carts = orderDTO.getCarts();
        // 获取所有sku的id
        List<Long> skuIdList = carts.stream().map(CartDTO::getSkuId).collect(Collectors.toList());
        // 处理CartDTO为一个map， 其key是skuId；值是num
        Map<Long, Integer> buyNumMap = carts.stream().collect(Collectors.toMap(CartDTO::getSkuId, CartDTO::getNum));
        // 1.3.1 查询sku
        List<SkuDTO> skuDTOS = itemClient.querySkusByIds(skuIdList);
        // 定义一个OrderDetail的集合
        ArrayList<OrderDetail> details = new ArrayList<>();
        // 1.3.2 计算金额的和
        Long total = 0L;
        // 计算总金额
        for (SkuDTO skuDTO : skuDTOS) {
            // 购买数量
            Integer num = buyNumMap.get(skuDTO.getId());
            total += skuDTO.getPrice() * num;
            // 组装OrderDetail
            OrderDetail orderDetail = new OrderDetail();
            orderDetail.setImage(StringUtils.substringBefore(skuDTO.getImages(), ","));
            orderDetail.setOrderId(orderId);
            orderDetail.setOwnSpec(skuDTO.getOwnSpec());
            orderDetail.setTitle(skuDTO.getTitle());
            orderDetail.setPrice(skuDTO.getPrice());
            orderDetail.setSkuId(skuDTO.getId());
            orderDetail.setNum(num);
            details.add(orderDetail);
        }
        // 1.3.3 填写金额数据
        order.setTotalFee(total);
        // 支付类型
        order.setPaymentType(orderDTO.getPaymentType());
        // 实付金额
        order.setActualFee(total + order.getPostFee()/*- 减去优惠价格*/);
        // 1.4 订单状态初始化
        order.setStatus(OrderStatusEnum.INIT.value());
        // 1.5 写order到数据库
        int insertCount = orderMapper.insertSelective(order);
        if (insertCount != 1) {
            throw new LyException(ExceptionEnum.INSERT_OPERATION_FAIL);
        }
        // 2 写OrderDetail
        int insertDetailsCount = orderDetailMapper.insertDetails(details);
        if (insertDetailsCount != details.size()) {
            throw new LyException(ExceptionEnum.INSERT_OPERATION_FAIL);
        }
        // 3 写orderLogistics
        // 3.1.查询收货地址
        AddressDTO addressDTO = userClient.queryAddressByUidAndId(userId, orderDTO.getAddressId());
        // 3.2.填写物流信息
        OrderLogistics orderLogistics = BeanHelper.copyProperties(addressDTO, OrderLogistics.class);
        orderLogistics.setOrderId(orderId);
        // 写入数据库
        int insertCountOrderLog = orderLogisticsMapper.insertSelective(orderLogistics);
        if (insertCountOrderLog != 1) {
            throw new LyException(ExceptionEnum.INSERT_OPERATION_FAIL);
        }
        // 4 减库存
        itemClient.minusStock(buyNumMap);
        return orderId;
    }

    @Override
    public OrderVO queryOrderById(Long orderId) {
        // 查询订单
        Order order = orderMapper.selectByPrimaryKey(orderId);
        if (order == null) {
            throw new LyException(ExceptionEnum.ORDER_NOT_FOUND);
        }
        //判断用户id是否正确
        Long userId = UserHolder.getUser();
        if (!order.getUserId().equals(userId)) {
            throw new LyException(ExceptionEnum.ORDER_NOT_FOUND);
        }
        //订单详情
        OrderDetail orderDetail = new OrderDetail();
        orderDetail.setOrderId(orderId);
        List<OrderDetail> orderDetailList = orderDetailMapper.select(orderDetail);
        if (CollectionUtils.isEmpty(orderDetailList)) {
            throw new LyException(ExceptionEnum.ORDER_DETAIL_NOT_FOUND);
        }
        //查询物流
        OrderLogistics orderLogistics = orderLogisticsMapper.selectByPrimaryKey(orderId);
        if (orderLogistics == null) {
            throw new LyException(ExceptionEnum.ORDER_NOT_FOUND);
        }
        OrderVO orderVO = BeanHelper.copyProperties(order, OrderVO.class);
        orderVO.setLogistics(BeanHelper.copyProperties(orderLogistics, OrderLogisticsVO.class));
        orderVO.setDetailList(BeanHelper.copyWithCollection(orderDetailList, OrderDetailVO.class));
        return orderVO;
    }
}
